package com.bysj.sausys.service.impl;

import com.bysj.sausys.beans.PageQuery;
import com.bysj.sausys.beans.PageResult;
import com.bysj.sausys.beans.Pagination;
import com.bysj.sausys.beans.SubmitTaskBean;
import com.bysj.sausys.common.ActArtConst;
import com.bysj.sausys.common.UserConst;
import com.bysj.sausys.common.WorkFlowConst;
import com.bysj.sausys.dao.SysActArtMapper;
import com.bysj.sausys.exception.ParamException;
import com.bysj.sausys.model.SysActArt;
import com.bysj.sausys.service.ISysActArtService;
import com.bysj.sausys.service.ISysWorkFlowService;
import com.bysj.sausys.util.ObjectUtils;
import com.bysj.sausys.util.PropertiesUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 推文Service接口实现
 *
 * @author WangZK
 */
@Service("sysActArtService")
public class SysActArtServiceImpl implements ISysActArtService {

    @Resource
    private SysActArtMapper sysActArtMapper;
    @Resource
    private ISysWorkFlowService sysWorkFlowService;

    /**
     * 保存推文
     *
     * @param sysActArt
     * @param map
     */
    @Override
    public void save(SysActArt sysActArt, Map map) {
        Integer assId = UserConst.getCurrentAssId(map);
        // 判断推文是否已经存在
        if (checkActArtExist(sysActArt.getId(), sysActArt.getType(), sysActArt.getTitle(), assId)) {
            throw new ParamException("推文/预告已存在，添加失败");
        }

        if (assId == -1) {
            sysActArt.setAuditStatus(ActArtConst.ACT_ART_AUDIT_PASS.getCode());
        } else {
            sysActArt.setAssId(assId);
        }

        sysActArt.setInsertMan(UserConst.getCurrentUsername(map));
        sysActArt.setInsertTime(new Date());
        sysActArtMapper.insertSelective(sysActArt);
    }

    /**
     * 判断推文/预告是否已存在
     *
     * @param id
     * @param type
     * @param title
     * @param assId
     * @return
     */
    private boolean checkActArtExist(Integer id, String type, String title, Integer assId) {
        return sysActArtMapper.countByTypeAndTitleAndAssId(id, type, title, assId) > 0;
    }

    /**
     * 更新推文
     *
     * @param sysActArt
     * @param map
     */
    @Override
    public void update(SysActArt sysActArt, Map map) {
        SysActArt before = sysActArtMapper.selectByPrimaryKey(sysActArt.getId());
        if (ActArtConst.NON_EDITABLE.getCode().equals(before.getEditStatus())) {
            throw new ParamException("推文为不可编辑状态，更新失败");
        }
        if (before == null) {
            throw new ParamException("待更新的推文不存在");
        }
        Integer assId = UserConst.getCurrentAssId(map);
        // 判断推文是否已经存在
        if (checkActArtExist(sysActArt.getId(), sysActArt.getType(), sysActArt.getTitle(), assId)) {
            throw new ParamException("推文/预告已存在，更新失败");
        }

        SysActArt after = new SysActArt();

        after.setId(sysActArt.getId());
        after.setType(sysActArt.getType());
        after.setTitle(sysActArt.getTitle());
        after.setContent(sysActArt.getContent());
        after.setShowStatus(sysActArt.getShowStatus());
        if (assId != null) {
            after.setAssId(assId);
        }
        after.setLastupdMan(UserConst.getCurrentUsername(map));
        after.setLastupdTime(new Date());
        sysActArtMapper.updateByPrimaryKeySelective(after);
    }

    /**
     * 根据id获取推文
     *
     * @param id
     * @return
     */
    @Override
    public SysActArt findById(Integer id) {
        return sysActArtMapper.selectByPrimaryKey(id);
    }

    /**
     * 分页获取推文列表
     *
     * @param pageQuery
     * @param map
     * @return
     */
    @Override
    public PageResult<SysActArt> getPage(PageQuery pageQuery, Map map) {
        Integer assId = UserConst.getCurrentAssId(map);
        if (assId == -1) {
            return getPageForAuditComp(pageQuery);
        } else {
            return getPageByAssId(pageQuery, assId);
        }
    }

    /**
     * 删除推文
     *
     * @param id
     */
    @Override
    public void delete(Integer id) {
        SysActArt sysActArt = sysActArtMapper.selectByPrimaryKey(id);
        if (sysActArt == null) {
            throw new ParamException("推文不存在，删除失败");
        }
        if (ActArtConst.NON_DELETING.getCode().equals(sysActArt.getDeleteStatus())) {
            throw new ParamException("该推文为不可删除状态，删除失败");
        }
        sysActArtMapper.deleteByPrimaryKey(id);
    }

    /**
     * 修改推文的展示状态
     *
     * @param id
     */
    @Override
    public void updateShowStatus(Integer id) {
        SysActArt sysActArt = sysActArtMapper.selectByPrimaryKey(id);
        // 判断推文是否审批通过
        if (!ActArtConst.ACT_ART_AUDIT_PASS.getCode().equals(sysActArt.getAuditStatus())) {
            throw new ParamException("审批未通过，推文不可以修改展示状态");
        }
        int showStatus = ActArtConst.SHOW.getCode();
        if (ActArtConst.SHOW.getCode().equals(sysActArt.getShowStatus())) {
            showStatus = ActArtConst.BLANK.getCode();
        }
        sysActArtMapper.updateShowStatus(id, showStatus);
    }

    /**
     * 根据社团id分页获取推文列表
     */
    private PageResult<SysActArt> getPageByAssId(PageQuery pageQuery, Integer assId) {
        int count = sysActArtMapper.countByAssId(assId);
        if (count > 0) {
            List<SysActArt> sysActArtList = sysActArtMapper.selectByAssId(pageQuery, assId);
            PageResult result = new PageResult();
            result.setList(sysActArtList);
            Pagination pagination = new Pagination();
            pagination.setTotal(count);
            pagination.setPageSize(pageQuery.getPageSize());
            pagination.setCurrentPage(pageQuery.getPageNo());
            result.setPagination(pagination);
            return result;
        }
        return new PageResult<>();
    }

    /**
     * 分页获取审批完成的推文列表
     *
     * @param pageQuery
     * @return
     */
    private PageResult<SysActArt> getPageForAuditComp(PageQuery pageQuery) {
        int count = sysActArtMapper.countByAuditStatus(ActArtConst.ACT_ART_AUDIT_PASS.getCode());
        if (count > 0) {
            List<SysActArt> sysActArtList = sysActArtMapper.selectByAuditStatus(ActArtConst.ACT_ART_AUDIT_PASS.getCode(), pageQuery);
            PageResult result = new PageResult();
            result.setList(sysActArtList);
            Pagination pagination = new Pagination();
            pagination.setTotal(count);
            pagination.setPageSize(pageQuery.getPageSize());
            pagination.setCurrentPage(pageQuery.getPageNo());
            result.setPagination(pagination);
            return result;
        }
        return new PageResult<>();
    }

    /**
     * 启动推文审批流程
     *
     * @param id
     * @param username
     */
    @Override
    public void saveStartProcess(Integer id, String username) {
        SysActArt sysActArt = sysActArtMapper.selectByPrimaryKey(id);
        if (sysActArt == null) {
            throw new ParamException("推文不存在，启动流程失败");
        }
        if (!ActArtConst.ACT_ART_INIT_ENTRY.getCode().equals(sysActArt.getAuditStatus())) {
            throw new ParamException("流程已启动，不需要再次启动");
        }

        //调用工作流的service，执行启动流程实例，让启动的流程实例关联业务的操作
        //1.通过配置文件获取流程定义的key
        String key = PropertiesUtil.getProperty(WorkFlowConst.ACT_ART_KEY.getCode());
        //2.设置字符串
        String objId = sysActArt.getClass().getSimpleName() + "." + id;

        String processInstanceId = sysWorkFlowService.saveStartProcess(key, objId, username);

        if (processInstanceId == null || "".equals(processInstanceId)) {
            throw new ParamException("启动推文审批流程失败");
        }

        //更改推文的状态
        Map map = new HashMap(4);
        map.put("id", id);
        map.put("deleteStatus", ActArtConst.NON_DELETING.getCode());
        map.put("editStatus", ActArtConst.NON_EDITABLE.getCode());
        map.put("auditStatus", ActArtConst.ACT_ART_AUDITING.getCode());
        sysActArtMapper.updateStatus(map);
    }

    /**
     * 获取审批信息
     *
     * @param taskId
     * @return
     */
    @Override
    public Map getAuditInfo(String taskId) {
        // 获取连线信息和历史审核人信息
        Map<String, Object> map = sysWorkFlowService.getAuditInfo(taskId);

        /**
         * 获取业务数据
         * 1.获取数据id
         * 2.根据id获取业务数据
         */
        int id = sysWorkFlowService.getBusinessIdByTaskId(taskId);
        SysActArt sysActArt = sysActArtMapper.selectByPrimaryKey(id);
        if (sysActArt == null) {
            throw new ParamException("获取推文失败");
        }
        try {
            Map objectMap = ObjectUtils.objectToMap(sysActArt);
            objectMap.remove("insertTime");
            objectMap.remove("insertMan");
            objectMap.remove("lastupdTime");
            objectMap.remove("lastupdMan");

            map.put("businessData", objectMap);
            map.put("taskId", taskId);

            return map;
        } catch (IllegalAccessException e) {
            throw new ParamException("获取推文失败");
        }
    }

    /**
     * 提交任务
     *
     * @param submitTaskBean
     * @param username
     */
    @Override
    public void saveSubmitTask(SubmitTaskBean submitTaskBean, String username) {
        //调用工作流封装好的方法
        String processInstanceId = sysWorkFlowService.saveSubmitTask(submitTaskBean, username, new HashMap(4));

        //判断是否需要更改申请表状态
        if (sysWorkFlowService.checkProcessIsEnd(processInstanceId)) {
            Map map = new HashMap(4);
            map.put("id", submitTaskBean.getId());
            map.put("deleteStatus", ActArtConst.DELETING.getCode());
            map.put("editStatus", ActArtConst.NON_EDITABLE.getCode());
            sysActArtMapper.updateStatus(map);
        }
    }


    /**
     * 获取历史的审批信息
     *
     * @param id
     * @return
     */
    @Override
    public Map getHisComment(Integer id) {
        SysActArt sysActArt = sysActArtMapper.selectByPrimaryKey(id);
        String objId = sysActArt.getClass().getSimpleName() + "." + id;

        Map<String, Object> map = sysWorkFlowService.findCommentByObjId(objId);

        try {
            Map objectMap = ObjectUtils.objectToMap(sysActArt);
            objectMap.remove("insertTime");
            objectMap.remove("insertMan");
            objectMap.remove("lastupdTime");
            objectMap.remove("lastupdMan");

            map.put("businessData", objectMap);
            return map;
        } catch (IllegalAccessException e) {
            throw new ParamException("获取推文失败");
        }
    }

    /**
     * 修改推文的状态
     *
     * @param map
     */
    @Override
    public void updateStatus(Map map) {
        sysActArtMapper.updateStatus(map);
    }

    /**
     * 根据推文类别和展示状态分页获取推文列表
     *
     * @param type
     * @param showStatus
     * @param pageQuery
     * @return
     */
    @Override
    public PageResult getPageByTypeAndShowStatus(String type, Integer showStatus, PageQuery pageQuery) {
        int count = sysActArtMapper.countByTypeAndShowStatus(type, showStatus);
        if (count > 0) {
            List<SysActArt> sysActArtList = sysActArtMapper.selectByTypeAndShowStatus(type, showStatus, pageQuery);
            PageResult result = new PageResult();
            result.setList(sysActArtList);
            Pagination pagination = new Pagination();
            pagination.setTotal(count);
            pagination.setPageSize(pageQuery.getPageSize());
            pagination.setCurrentPage(pageQuery.getPageNo());
            result.setPagination(pagination);
            return result;
        }
        return new PageResult<>();
    }

    /**
     * 根据社团id和展示状态分页获取推文列表
     * @param assId
     * @param showStatus
     * @param pageQuery
     * @return
     */
    @Override
    public PageResult getPageByAssIdAndShowStatus(Integer assId, Integer showStatus, PageQuery pageQuery) {
        int count = sysActArtMapper.countByAssIdAndShowStatus(assId, showStatus);
        if (count > 0) {
            List<SysActArt> sysActArtList = sysActArtMapper.selectByAssIdAndShowStatus(assId, showStatus, pageQuery);
            PageResult result = new PageResult();
            result.setList(sysActArtList);
            Pagination pagination = new Pagination();
            pagination.setTotal(count);
            pagination.setPageSize(pageQuery.getPageSize());
            pagination.setCurrentPage(pageQuery.getPageNo());
            result.setPagination(pagination);
            return result;
        }
        return new PageResult<>();
    }
}
